/* PROJECTO: Projecto 3
 * FICHEIRO: tabuleiro.cpp
 *
 * DESCRIÇÃO: Codigo correspondente ao tabuleiro.
 *            Nao implementa os metodos TirarCartaSorte(), e ComprarCasa(Jogador& Player, Casa& casa)
 *            
 *
 * TURMA / GRUPO: Turma 1 / Grupo 12
 * AUTORES: Fábio Domingo da Silva Rodrigues
 *          Rolando Emanuel Lopes Pereira
 *
 * DECLARAÇÃO:
 * Declaramos sob compromisso de honra que este trabalho nas suas partes
 * constituintes de código (e relatório, se aplicável) é original e da nossa
 * autoria, não correspondendo, portanto, a cópia ou tradução de outros
 * trabalhos já realizados, na FEUP ou fora dela.
 * Mais declaramos que todos os documentos ou código que serviram de base ao
 * desenvolvimento do trabalho descrito no relatório e seus anexos são
 * adequadamente citados e explicados na respectiva secção de referências
 * bibliográficas e que todas as eventuais partes transcritas ou utilizadas de
 * outras fontes estão devidamente assinaladas, identificadas e evidenciadas.
 * Subscrevemos a declaração acima:
 * Fábio Domingo da Silva Rodrigues
 * Rolando Emanuel Lopes Pereira
 *
 * REFERÊNCIAS E FONTES DE INFORMAÇÃO UTILIZADAS:
 *
 * SISTEMA OPERATIVO:
 * Debian 4.0
 * AMBIENTE DE DESENVOLVIMENTO:
 * Vim 7.0.235
 *
 * DATA DE INÍCIO: 20/05/2009
 * DATA DE CONCLUSÃO: 30/05/2009
 *
 * */

#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include "tabuleiro.h"

using std::vector;
using std::string;
using std::cin;
using std::ifstream;
using std::cout;
using std::endl;


Tabuleiro::Tabuleiro(Jogador& Player1, Jogador& Player2)
{
    srand(time(NULL));
}

Tabuleiro::Tabuleiro()
{
    srand(time(NULL));
}

Tabuleiro::~Tabuleiro()
{

}

void Tabuleiro::addJogadores(Jogador& Player1, Jogador& Player2)
{
    Player1.addDinheiro(DinheiroInicial);
    Player2.addDinheiro(DinheiroInicial);
    
    Jog1 = Player1;
    Jog2 = Player2;
}

void Tabuleiro::addCasa(string nome, int custo, string tipo, int renda_base, int valor_casa, int renda_casa)
{
    Casa temp_casa(Casas.size() + 1, nome, custo, tipo, renda_base, valor_casa, renda_casa);
    Casas.push_back(temp_casa);
}

Casa& Tabuleiro::getCasa(int n)
{
    return Casas[n-1];
}

Casa& Tabuleiro::getCasa(string nome)
{
    typedef vector<Casa>::size_type v_st;
    
    for (v_st k = 0; k != Casas.size(); k++)
    {
        if (Casas[k].getNome() == nome)
            return Casas[k];
    }
}

void Tabuleiro::VisualizarTabuleiro()
{

    cout << ".---------------------------------------." << endl
         << "| 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |" << endl
         << "|----+----+----+----+----+----+----+----|" << endl
         << "| 14 |    |    |    |    |    |    | 23 |" << endl
         << "|----+----+----+----+----+----+----+----|" << endl
         << "| 13 |    |    |    |    |    |    | 24 |" << endl
         << "|----+----+----+----+----+----+----+----|" << endl
         << "| 12 |    |    |    |    |    |    | 25 |" << endl
         << "|----+----+----+----+----+----+----+----|" << endl
         << "| 11 |    |    |    |    |    |    | 26 |" << endl
         << "|----+----+----+----+----+----+----+----|" << endl
         << "| 10 |    |    |    |    |    |    | 27 |" << endl
         << "|----+----+----+----+----+----+----+----|" << endl
         << "|  9 |    |    |    |    |    |    | 28 |" << endl
         << "|----+----+----+----+----+----+----+----|" << endl
         << "|  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |" << endl
         << "'---------------------------------------'" << endl
         << endl;
    

    // typedef vector<Casa>::size_type v_st;

    // for (v_st k = 0; k != Casas.size(); k++)
    // {
    //     Casa casa = Casas[k];

    //     cout << "Casa: " << casa.getNome() << endl
    //          << "Posicao: " << casa.getPosicao() << endl
    //          << "Custo: " << casa.getCusto() << endl
    //          << "Renda Base: " << casa.getRendaBase() << endl
    //          << "Valor Casa: " << casa.getValorCasa() << endl
    //          << "Tipo: " << casa.getTipo() << endl
    //          << endl;
    // }

    for (int k = 0; k != GruposCasas.size(); k++)
    {
        cout << "Grupo de casas " << k << ": ";
        
        for (int i = 0; i != GruposCasas[k].size(); i++)
        {
            cout << GruposCasas[k][i] << " ";
        }
        cout << endl;
    }
}

Casa& Tabuleiro::TirarCartaSorte()
{
}

void Tabuleiro::LerFicheiroTabuleiro(string nomeficheiro)
{
    string linha;

    // Primeira linha contem o dinheiro e o numero de casas que o tabuleiro contem

    ifstream ficheiro(nomeficheiro.c_str());

    // TODO: Usar isto
    // if (!ficheiro.is_open())
    // {
    // }
    
    ficheiro >> DinheiroInicial;

    int n_casas;
    ficheiro >> n_casas;

    // Limpar buffer
    getline(ficheiro, linha);

    typedef string::size_type int_st;
    // Durante as proximas "n_casas" esta a informacao sobre as casa do tabuleiro
    for (int k = 0; k != n_casas; k++)
    {
        getline(ficheiro, linha);


        
        int_st primeira_barra = linha.find("|");
        int_st segunda_barra = linha.find("|", primeira_barra+1);

        string nome_casa = linha.substr(primeira_barra+1, segunda_barra-1);

        
        if (nome_casa == "Casa Neutra")
        {
            addCasa("Casa Neutra", 0, "Neutra", 0, 0, 0);
            continue;
        }

        int_st terceira_barra = linha.find("|", segunda_barra+1);

        string tipo_casa = linha.substr(segunda_barra+1, terceira_barra-segunda_barra-1);

        
        if (tipo_casa == "CasaPartida")
        {
            int size_linha = linha.size();
            size_linha = size_linha - 2;
            
            
            //FIXME: Mudar isto para int e usar o atoi (ou itoi)
            int dinheiro_ganho = atoi(linha.substr(terceira_barra+1, size_linha).c_str());

            addCasa(nome_casa, 0, "CasaPartida", dinheiro_ganho, 0, 0);
            continue;
            
        }
        if (tipo_casa == "Divida")
        {
            int size_linha = linha.size();
            size_linha = size_linha - 1;
            
            
            //FIXME: Mudar isto para int e usar o atoi (ou itoi)
            int divida = atoi(linha.substr(terceira_barra+1, size_linha).c_str());

            addCasa(nome_casa, 0, "Divida", divida, 0, 0);
            continue;
            
        }

        else // E uma propriedade
        {
            int_st quarta_barra = linha.find("|", terceira_barra+1);
            //string custo = linha.substr(terceira_barra, quarta_barra);
            int custo = atoi(linha.substr(terceira_barra+1, quarta_barra-terceira_barra-1).c_str());

            int_st quinta_barra = linha.find("|", quarta_barra+1);
            //string renda = linha.substr(quarta_barra, quinta_barra);
            int renda = atoi(linha.substr(quarta_barra+1, quinta_barra-quarta_barra-1).c_str());
            //int irenda = atoi(renda.c_str());
            
            int_st sexta_barra = linha.find("|", quinta_barra+1);
            //string valor_cons_casa = linha.substr(quinta_barra, sexta_barra);
            int valor_cons_casa = atoi(linha.substr(quinta_barra+1, sexta_barra-quinta_barra-1).c_str());

            int_st setima_barra = linha.find("|", sexta_barra+1);
            //string renda_por_casa = linha.substr(sexta_barra, setima_barra);
            int renda_por_casa = atoi(linha.substr(sexta_barra+1, setima_barra-sexta_barra-1).c_str());

            addCasa(nome_casa, custo, "Propriedade", renda, valor_cons_casa, renda_por_casa);
        }
    }

    getline(ficheiro, linha);

    if (linha == "[SORTE]")
    {
        int n_cartas;
        ficheiro >> n_cartas;

        // Limpar buffer
        getline(ficheiro, linha);
        
        for (int k = 0; k != n_cartas; k++)
        {
            getline(ficheiro, linha);
            
            int_st primeira_barra = linha.find("|");
            int_st segunda_barra = linha.find("|", primeira_barra+1);

            // Numero de vezes que essa carta vai aparecer no baralho
            int n_carta = atoi(linha.substr(primeira_barra+1, segunda_barra-1).c_str());

            int_st terceira_barra = linha.find("|", segunda_barra+1);

            string nome_carta = linha.substr(segunda_barra+1, terceira_barra - segunda_barra-1);

            int_st quarta_barra = linha.find("|", terceira_barra+1);

            string tipo_carta = linha.substr(terceira_barra+1, quarta_barra - terceira_barra-1);

            int_st quinta_barra = linha.find("|", quarta_barra+1);

            int valor = atoi(linha.substr(quarta_barra+1, quinta_barra - quarta_barra-1).c_str());

            for (int i = 0; i != n_carta; i++)
                addCartaSorte(nome_carta, tipo_carta, valor);
        }
    }

    // Apanhar o [/SORTE]
    getline(ficheiro, linha);

    getline(ficheiro, linha);
    if (linha == "[GRUPO_CASAS]")
    {
        int n_grupos;
        ficheiro >> n_grupos;

        // Limpar buffer
        getline(ficheiro, linha);

        bool continuar = false;

        // TODO: Isto ficava bonito era recursivo :(
        // while (!continuar)
        // {
        //     getline(ficheiro, linha);

        //     int_st barra_esquerda = linha.find("|");
        //     int_st barra_direita = linha.find("|", barra_esquerda+1);
        // }
        
        for (int i = 0; i != n_grupos; i++)
        {
            getline(ficheiro, linha);

            int_st primeira_barra = linha.find("|");

            int_st segunda_barra = linha.find("|", primeira_barra+1);

            int casa1 = atoi(linha.substr(primeira_barra+1, segunda_barra-1).c_str());
            int_st terceira_barra = linha.find("|", segunda_barra+1);

            int casa2 = atoi(linha.substr(segunda_barra+1, terceira_barra-segunda_barra-1).c_str());

            int_st quarta_barra = linha.find("|", terceira_barra+1);

            if (quarta_barra == string::npos)
            {
                vector<int> temp_vector;
                temp_vector.push_back(casa1);
                temp_vector.push_back(casa2);
                
                GruposCasas.push_back(temp_vector);
                
                
            }
            else
            {
                int casa3 = atoi(linha.substr(terceira_barra+1, quarta_barra-terceira_barra-1).c_str());

                vector<int> temp_vector;
                temp_vector.push_back(casa1);
                temp_vector.push_back(casa2);
                temp_vector.push_back(casa3);

                GruposCasas.push_back(temp_vector);
            }
        }
    }
}

void Tabuleiro::addCartaSorte(string nome, string tipo, int custo)
{
    Casa temp_carta(CartasSorte.size() + 1, nome, custo, tipo, 0, 0, 0);
    CartasSorte.push_back(temp_carta);
}

void Tabuleiro::ComprarCasa(Jogador& Player, Casa& casa)
{
}

void Tabuleiro::AvancarJogador(Jogador* jogador, int casas)
{
    // Jogador *jogActual;
    
    // if (jogador == 1)
    //     jogActual = &Jog1;
    // else
    //     jogActual = &Jog2;
    
    for (int i = 0; i != casas; i++)
    {
        jogador->setPosicao(jogador->getPosicao()+1);

        // Verificar se ja se encontra no limite do tabuleiro
        if (jogador->getPosicao() == 28)
        {
            jogador->setPosicao(0);
            Casa partida = getCasa(1);
            jogador->addDinheiro(partida.getRendaBase());
        }
    }
}
